//authored by alpc40
//version：visual studio 2015\cuda toolkit 8.0\openCV 3.2.0
/*
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include<opencv2/opencv.hpp>
using namespace cv;
//出错处理函数
#define CHECK_ERROR(call){\
    const cudaError_t err = call;\
    if (err != cudaSuccess)\
    {\
        printf("Error:%s,%d,",__FILE__,__LINE__);\
        printf("code:%d,reason:%s\n",err,cudaGetErrorString(err));\
        exit(1);\
    }\
}
//内核函数：实现上下翻转
__global__ void swap_image_kernel(cuda::PtrStepSz<uchar3> cu_src, cuda::PtrStepSz<uchar3> cu_dst, int h, int w)
{
    //计算的方法：参看前面两文
    unsigned int x = blockDim.x * blockIdx.x + threadIdx.x;
    unsigned int y = blockDim.y * blockIdx.y + threadIdx.y;
    //为啥要这样限制：参看前面两文
    if (x < cu_src.cols && y < cu_src.rows)
    {
        //为何不是h-y-1,而不是h-y，自己思考哦
        cu_dst(y, x) = cu_src(h - y - 1, x);
    }
}
//调用函数，主要处理block和grid的关系，注意extern哦，它是库文件编写规范
extern "C" void swap_image(cuda::GpuMat src, cuda::GpuMat dst, int h, int w)
{
    assert(src.cols == w && src.rows == h);
    int uint = 32;
    //参考前面两文的block和grid的计算方法，注意不要超过GPU限制
    dim3 block(uint, uint);
    dim3 grid((w + block.x - 1) / block.x, (h + block.y - 1) / block.y);
    printf("grid = %4d %4d %4d\n", grid.x, grid.y, grid.z);
    printf("block= %4d %4d %4d\n", block.x, block.y, block.z);
    swap_image_kernel << <grid, block >> > (src, dst, h, w);
    //同步一下，因为计算量可能很大
    CHECK_ERROR(cudaDeviceSynchronize());
}
*/